home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / New System Software Extensions / ASLM SDK v1.1.2 / ASLM Examples / TestTools / Sources / TestStandardPool.cp < prev    next >
Encoding:
Text File  |  1994-11-21  |  10.2 KB  |  460 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        TestStandardPool.cp
  3.  
  4.     Contains:    Methods for TTestStandardPool
  5.  
  6.     Copyright:    © 1992-1993 by Apple Computer, Inc., all rights reserved.
  7.  
  8. */
  9.  
  10. #ifndef __GLOBALNEW__
  11. #include <GlobalNew.h>
  12. #endif
  13. #ifndef __TESTSTANDARDPOOL__
  14. #include "TestStandardPool.h"
  15. #endif
  16.  
  17. /*******************************************************************************
  18. ** CLASS Declaration
  19. ********************************************************************************/
  20.  
  21. class TMyPoolNotifier : public TPoolNotifier
  22. {
  23.     public:
  24.                             TMyPoolNotifier(void* memory);
  25.         virtual                ~TMyPoolNotifier();
  26.         
  27.         virtual void        Notify(EventCode, OSErrParm, void*);
  28.         
  29.     private:
  30.         void*    fMemory;
  31. };
  32.  
  33. TMyPoolNotifier::TMyPoolNotifier(void* memory)
  34. {
  35.     fMemory = memory;
  36. }
  37.  
  38. TMyPoolNotifier::~TMyPoolNotifier()
  39. {}
  40.  
  41. void TMyPoolNotifier::Notify(EventCode code, OSErrParm err, void*)
  42. {
  43.     if (code == kLowPoolMemoryEvent && err == kNoError)
  44.     {
  45.         if (fMemory)
  46.         {
  47.             TMemoryPool::FreeMemory(fMemory);
  48.             fMemory = NULL;
  49.         }
  50.     }
  51. }
  52. /**********************************************************************
  53. ** External "C" Declarations
  54. ***********************************************************************/
  55.  
  56. extern "C"
  57. {
  58.     short pcli() = 
  59.     {
  60.         0x40c0,                        /* move  SR,D0        */
  61.         0x007C, 0x0700,                /* ori.w #$0700,SR    */
  62.         0x027C, 0xFEFF                /* andi.w #$FEFF,SR    */
  63.     };
  64.     
  65.     #pragma parameter psti(__D0)
  66.     void psti(short) = 
  67.     {
  68.         0x46c0                        /* move.w D0,SR        */
  69.     };
  70. };
  71.  
  72. /*******************************************************************************
  73. ** Some Constants
  74. ********************************************************************************/
  75.  
  76. const size_t    kNumPoolOps        = 5;
  77. const size_t    kNumMemory        = 25;
  78. const size_t    kMaxMemSize        = 255;
  79.  
  80. #define kDontTouch    ((char*)-1L)
  81.  
  82. /*******************************************************************************
  83. ** TPoolTestOperation
  84. ********************************************************************************/
  85.  
  86. TPoolTestOperation::TPoolTestOperation(char** array, size_t size, size_t small,
  87.                                        size_t large)
  88. {
  89.     fArray        = array;
  90.     fArraySize    = size;
  91.     fFinished    = true;
  92.     fSmallest    = small;
  93.     fLargest    = large;
  94.     fAllocs        = 0;
  95.     fDeletes    = 0;
  96. }
  97.  
  98. TPoolTestOperation::~TPoolTestOperation()
  99. {}
  100.  
  101. void TPoolTestOperation::Process()
  102. {
  103.     size_t toAlloc = RandomNumber(0, fArraySize);
  104.     size_t count = 0;
  105.     for (count = 0; count < toAlloc; ++count)
  106.     {
  107.         size_t which = RandomNumber(0, fArraySize - 1);
  108.         if (fArray[which] == NULL)
  109.         {
  110.             char* temp = new char[RandomNumber(fSmallest, fLargest)];
  111.             fAllocs += 1;
  112.             short save = pcli();
  113.             if (fArray[which] == NULL)
  114.             {
  115.                 fArray[which] = temp;
  116.                 psti(save);
  117.             }
  118.             else
  119.             {
  120.                 psti(save);
  121.                 delete temp;
  122.                 fDeletes += 1;
  123.             }
  124.         }
  125.     }
  126.     size_t toFree = RandomNumber(0, fArraySize);
  127.     for (count = 0; count < toFree; ++count)
  128.     {
  129.         size_t which = RandomNumber(0, fArraySize - 1);
  130.         short save = pcli();
  131.         if (fArray[which] != NULL && fArray[which] != kDontTouch)
  132.         {
  133.             char* temp = fArray[which];
  134.             fArray[which] = NULL;
  135.             psti(save);
  136.             delete temp;
  137.             fDeletes += 1;
  138.         }
  139.         else
  140.             psti(save);
  141.     }
  142.     fFinished = true;
  143. }
  144.  
  145. /*******************************************************************************
  146. ** PUBLIC Constructor/Destructor
  147. ********************************************************************************/
  148.  
  149. Constructor(StandardPool)
  150. Destructor(StandardPool)
  151.  
  152. /*******************************************************************************
  153. ** PUBLIC InitTest
  154. ********************************************************************************/
  155.  
  156. void TTestStandardPool :: InitTest(Boolean verbose, Boolean, int argc, char** argv)
  157. {
  158.     TStandardPool* pool = GetPool();
  159.         
  160.     if (pool == NULL)
  161.     {
  162.         Printf("### ERROR: There is no global pool\n");
  163.         return;
  164.     }
  165.         
  166.     SetLocalPool(pool);
  167.     
  168.     fSmallest    = 1;
  169.     fLargest    = 255;
  170.     fAllocs        = 0;
  171.     fDeletes    = 0;
  172.     fReallocs    = 0;
  173.     fIterations = 1000;
  174.     size_t    idx = 0;
  175.     while (argc)
  176.     {
  177.         char*    str;
  178.         
  179.         str = argv[idx];
  180.         if (*str != '-')
  181.             break;
  182.         argc -= 1;
  183.         idx += 1;
  184.         switch (str[1])
  185.         {
  186.             case 'i':
  187.             case 'I':
  188.                 fIterations = NumToString(argv[idx++]);
  189.                 argc -= 1;
  190.                 break;
  191.                 
  192.             default: 
  193.                 argc = 0;
  194.                 Printf("WARNING: Option at and after '%s' not understood!\n", str);
  195.                 break;
  196.         }
  197.  
  198.     }
  199.     fSmallest     = 1;
  200.     fLargest    = 255;
  201.     if (argc)
  202.     {
  203.         if (argc == 1)
  204.             Printf("WARNING: Option '%s' not understood!\n", argv[idx]);
  205.         else
  206.         if (argc != 2)
  207.             Printf("WARNING: Options at and after '%s' not understood!\n",
  208.                    argv[idx]);
  209.         else
  210.         {
  211.             fSmallest = NumToString(argv[idx++]);
  212.             fLargest = NumToString(argv[idx++]);
  213.             if (verbose)
  214.                 Printf("INFO: Smallest size = %u\nINFO: Largest size = %u\n",
  215.                        fSmallest, fLargest);
  216.         }
  217.     }
  218. }
  219.  
  220.  
  221. /**********************************************************************
  222. ** PUBLIC RunTestIteration
  223. ***********************************************************************/
  224.  
  225. void TTestStandardPool :: RunTestIteration(Boolean verbose, Boolean)
  226. {
  227.     TPoolTestOperation*    ops[kNumPoolOps];
  228.     TTimeScheduler*        sched = new TTimeScheduler;
  229.     char*                memory[kNumMemory];
  230.     size_t                idx, jdx;
  231.     TStopwatch            stamp;
  232.     
  233.     //
  234.     // First, we do some quick tests on the pool
  235.     //
  236.     {
  237.         if (verbose)
  238.             Printf("### INFO: Testing Pool Notifiers\n");
  239.         TStandardPool* pool = new (2500, kCurrentZone, kNormalMemory) TStandardPool;
  240.         if (pool)
  241.         {
  242.             void* memory = pool->Allocate(2000);
  243.             if (memory == NULL)
  244.             {
  245.                 Printf("### ERROR: Couldn't allocate 2000 bytes from a 2500 byte pool\n");
  246.             }
  247.             else
  248.             {
  249.                 Boolean ok = true;
  250.                 void* mem2 = pool->Allocate(2000);
  251.                 if (mem2)
  252.                 {
  253.                     Printf("### ERROR: Allocated 4000 bytes from a 2500 byte pool\n");
  254.                     ok = false;
  255.                     pool->Free(mem2);
  256.                 }
  257.                 else
  258.                 {
  259.                     TMyPoolNotifier    notifier(memory);
  260.                     pool->SetNotifier(¬ifier);
  261.                     mem2 = pool->Allocate(2000);
  262.                     if (mem2 == NULL)
  263.                     {
  264.                         ok = false;
  265.                         Printf("### ERROR: Couldn't allocate 2000 bytes using the notifier\n");
  266.                     }
  267.                     void* mem3 = pool->Allocate(2000);
  268.                     if (mem3 == NULL)
  269.                     {
  270.                         Printf("### ERROR: Pool didn't grow\n");
  271.                         ok = false;
  272.                     }
  273.                     else
  274.                         pool->Free(mem3);
  275.                     if (mem2)
  276.                         pool->Free(mem2);
  277.                     pool->SetNotifier(NULL);
  278.                     if (verbose && ok)
  279.                         Printf("### INFO: Pool notifiers seemed to work!\n");
  280.                 }
  281.             }
  282.             delete pool;
  283.         }
  284.         else
  285.             Printf("### ERROR: Couldn't create a 2500 byte pool\n");
  286.     }
  287.         
  288.     memset(memory, 0, sizeof(memory));
  289.     
  290.     for (idx = 0; idx < kNumPoolOps; ++idx)
  291.         ops[idx] = new TPoolTestOperation(memory, kNumMemory, fSmallest, fLargest);
  292.     
  293.     (&stamp)->Reset();
  294.     
  295.     Printf("       0: ");
  296.     for (idx = 0; idx < fIterations; ++idx)
  297.     {
  298.         if ((idx + 1) % 10 == 0)
  299.             Printf(".");
  300.         if ((idx + 1) % 500 == 0)
  301.             Printf("\n%8u: ", idx + 1);
  302.         //
  303.         // Schedule any operations that are not scheduled
  304.         //
  305.         for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  306.             if (ops[jdx]->fFinished)
  307.             {
  308.                 ops[jdx]->fFinished = false;
  309.                 ops[jdx]->SetTime(jdx + 1);
  310.                 sched->Schedule(ops[jdx]);
  311.             }
  312.         
  313.         size_t toAlloc = RandomNumber(0, kNumMemory);
  314.         size_t count = 0;
  315.         for (count = 0; count < toAlloc; ++count)
  316.         {
  317.             size_t which = RandomNumber(0, kNumMemory - 1);
  318.             if (memory[which] == NULL)
  319.             {
  320.                 size_t size = RandomNumber(fSmallest, fLargest);
  321.                 char* temp = new char[size];
  322.                 fAllocs += 1;
  323.                 short save = pcli();
  324.                 if (memory[which] == NULL)
  325.                 {
  326.                     memory[which] = temp;
  327.                     psti(save);
  328.                 }
  329.                 else
  330.                 {
  331.                     psti(save);
  332.                     delete temp;
  333.                     fDeletes += 1;
  334.                 }
  335.             }
  336.         }
  337.         //
  338.         // Schedule any operations that are not scheduled
  339.         //
  340.         for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  341.             if (ops[jdx]->fFinished)
  342.             {
  343.                 ops[jdx]->fFinished = false;
  344.                 ops[jdx]->SetTime(jdx + 1);
  345.                 sched->Schedule(ops[jdx]);
  346.             }
  347.             
  348.         size_t toFree = RandomNumber(0, kNumMemory);
  349.         for (count = 0; count < toFree; ++count)
  350.         {            
  351.             size_t which = RandomNumber(0, kNumMemory - 1);
  352.             short save = pcli();
  353.             if (memory[which] != NULL && memory[which] != kDontTouch)
  354.             {
  355.                 char* temp = memory[which];
  356.                 memory[which] = NULL;
  357.                 psti(save);
  358.                 delete temp;
  359.                 fDeletes += 1;
  360.             }
  361.             else
  362.                 psti(save);
  363.         }
  364.         //
  365.         // Schedule any operations that are not scheduled
  366.         //
  367.         for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  368.             if (ops[jdx]->fFinished)
  369.             {
  370.                 ops[jdx]->fFinished = false;
  371.                 ops[jdx]->SetTime(jdx + 1);
  372.                 sched->Schedule(ops[jdx]);
  373.             }
  374.  
  375.         size_t toResize = RandomNumber(0, kNumMemory);
  376.         for (count = 0; count < toResize; ++count)
  377.         {            
  378.             size_t which = RandomNumber(0, kNumMemory - 1);
  379.             size_t newSize = RandomNumber(fSmallest, fLargest);
  380.             short save = pcli();
  381.             if (memory[which] != NULL && memory[which] != kDontTouch)
  382.             {
  383.                 char* temp = memory[which];
  384.                 memory[which] = kDontTouch;
  385.                 psti(save);
  386.                 char* temp1 = (char*)TMemoryPool::ReallocateMemory(temp, newSize);
  387.                 fReallocs += 1;
  388.                 save = pcli();
  389.                 memory[which] = temp1;
  390.                 psti(save);
  391.                 if (temp1 == NULL)
  392.                 {
  393.                     fDeletes += 1;
  394.                     delete temp;
  395.                 }
  396.             }
  397.             else
  398.                 psti(save);
  399.         }
  400.         //
  401.         // Schedule any operations that are not scheduled
  402.         //
  403.         for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  404.             if (ops[jdx]->fFinished)
  405.             {
  406.                 ops[jdx]->fFinished = false;
  407.                 ops[jdx]->SetTime(jdx + 1);
  408.                 sched->Schedule(ops[jdx]);
  409.             }
  410.  
  411.         if (!GetDefaultPool()->CheckPool())
  412.         {
  413.             Printf("\nERROR: CheckPool() Failed ... ABORTING TEST\n");
  414.             break;
  415.         }
  416.     }
  417.     for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  418.         if (!ops[jdx]->fFinished)
  419.             jdx = 0;
  420.             
  421.     unsigned long seconds = (&stamp)->ElapsedSeconds();
  422.     unsigned long allocs, frees, reallocs;
  423.     allocs = fAllocs;
  424.     frees = fDeletes;
  425.     reallocs = fReallocs;
  426.     if (seconds == 0)
  427.         seconds = 1;
  428.     for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  429.     {
  430.         allocs += ops[jdx]->fAllocs;
  431.         frees += ops[jdx]->fDeletes;
  432.     }
  433.     
  434.     delete sched;
  435.     for (jdx = 0; jdx < kNumPoolOps; ++jdx)
  436.     {
  437.         TPoolTestOperation* op = ops[jdx];
  438.         delete op;
  439.     }
  440.     for (jdx = 0; jdx < kNumMemory; ++jdx)
  441.         delete memory[jdx];
  442.         
  443.     if (verbose)
  444.     {
  445.         Printf("\n\nINFO: # Allocates   = %8u   per second = %4u\n", allocs, allocs/seconds);
  446.         Printf("INFO: # Deletes     = %8u   per second = %4u\n", frees, frees/seconds);
  447.         Printf("INFO: # Reallocates = %8u   per second = %4u\n\n", reallocs, reallocs/seconds);
  448.     }        
  449. }
  450.  
  451. /**********************************************************************
  452. ** PUBLIC EndTest
  453. ***********************************************************************/
  454.  
  455. void TTestStandardPool :: EndTest(Boolean verbose, Boolean)
  456. {
  457.     if (verbose)
  458.         Printf("INFO: End of StandardPool test\n");
  459. }
  460.